package org.example;

import com.lowagie.text.*;
import com.lowagie.text.Font;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.*;
import com.lowagie.text.pdf.draw.LineSeparator;
import org.example.vo.Order;

import java.awt.*;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class PdfCreator {
    /**
     * 页框大小,采用的类型有 "crop", "trim", "art" and "bleed".，这里采用 "art"
     */
    private static final String BOX_NAME = "art";

    protected Document document;
    /**
     * 字体大小
     */
    protected int fontSize;
    /**
     * 字体样式
     */
    protected Font font;

    /**
     * 页面框架大小配置
     */
    protected Rectangle pageSize;
    /**
     * 字节输出流
     */
    protected ByteArrayOutputStream byteArrayOutputStream;


    /**
     * 设置全局字体、字号
     */
    private static BaseFont baseFont;
    private static Font font12;
    private static Font font10;
    private static Font font8;
    private static Font font14Under;

    static {
        try {
            //使用iTextAsian.jar中的字体、并设置编码
            baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            font12 = new Font(baseFont, 12,Font.NORMAL);
            font10 = new Font(baseFont, 10,Font.NORMAL);
            font8 = new Font(baseFont, 8,Font.NORMAL);
            font14Under = new Font(baseFont, 14, Font.UNDERLINE);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 默认初始化
     *
     * @return PdfCreator
     * @throws DocumentException 文档操作异常
     * @throws IOException       IO操作异常
     */

    public PdfCreator init() throws DocumentException, IOException {
        return init(baseFont, fontSize, font, pageSize, null);
    }

    /**
     * 自定义初始化监听
     *
     * @param helper 自定义文档操作监听
     * @return PdfCreator
     * @throws DocumentException 文档操作异常
     * @throws IOException       IO操作异常
     */
    public PdfCreator init(PdfPageEventHelper helper) throws DocumentException, IOException {
        return init(baseFont, fontSize, font, pageSize, helper);
    }


    public PdfCreator init(BaseFont baseFont, int fontSize, Font font, Rectangle rectangle, PdfPageEventHelper pdfPageEventHelper) throws DocumentException, IOException {
        this.baseFont = null != baseFont ? baseFont : BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", Boolean.FALSE);
        this.fontSize = 0 != fontSize ? fontSize : Header.PARAGRAPH;
        this.font = null != font ? font : new Font(this.baseFont, this.fontSize, Font.NORMAL);
        this.pageSize = null != pageSize ? pageSize : PageSize.A4;

        document = new Document();
        document.setMargins(30, 30, 50, 90);
        byteArrayOutputStream = new ByteArrayOutputStream();
        PdfWriter writer = PdfWriter.getInstance(document, byteArrayOutputStream);
        writer.setBoxSize(BOX_NAME, this.pageSize);
        if (null != pdfPageEventHelper) {
            writer.setPageEvent(pdfPageEventHelper);
        }
        document.open();
        return this;
    }

    /**
     *  map中可以存放实体类信息，以及其他各种逻辑数据信息等
     * @param map
     * @throws DocumentException
     * @throws IOException
     */
    public void execute(Map<String, Object> map) throws DocumentException, IOException {
        //   Order order = (Order) map.get("data");
        BaseFont fontChinese = BaseFont.createFont("STSong-Light","UniGB-UCS2-H",BaseFont.NOT_EMBEDDED);//设置中文字体
        Font titleFont = new Font(fontChinese, 18, Font.BOLD);
        Paragraph title = new Paragraph("录 取 通 知 书", titleFont);
        title.setAlignment(Element.ALIGN_CENTER);
        title.setSpacingAfter(10F);
        document.add(title);

        // 字体居右
        Paragraph number = new Paragraph("(编号：12345678)",font10);
        number.setAlignment(Element.ALIGN_RIGHT );
        number.setIndentationRight(35F);
        document.add(number);


        // 实线
        Paragraph line = new Paragraph("",font10);
        line.add(new Chunk(new LineSeparator(1,100, Color.BLACK,1,5)));
        document.add(line);

        //空行
        Paragraph blankLine = new Paragraph("\n", font12);
        document.add(blankLine);
        //段落内容
        Paragraph receiver = new Paragraph("韩梅梅", font12);
        receiver.setLeading(5);
        document.add(receiver);

        Paragraph paragraphText = new Paragraph();
        Font font1 = new Font(baseFont, fontSize, Font.NORMAL);
        paragraphText.add(new Chunk("贵阳，简称“筑”，别称林城、筑城，贵州省辖地级市、省会、Ⅰ型大城市，国务院批复确定的中国西南地区重要的中心城市之一" +
                " 重要的区域创新中心和全国重要的生态休闲度假旅游城市。" +
                " 贵阳地处黔中山原丘陵中部，东南与黔南布依族苗族自治州的瓮安、龙里、惠水、长顺4县接壤，" +
                " 西靠安顺市的平坝区和毕节市的织金县，北邻毕节市的黔西市、金沙县和遵义市的播州区，" +
                " 截至2020年，全市下辖6个区、3个县，代管1个县级市。截至2021年末，贵阳市常住人口610.23万人。", font1));
        //设置段落内行间距，也可使用构造器设置
        paragraphText.setAlignment(Element.ALIGN_LEFT);
        //首行缩进
        paragraphText.setFirstLineIndent(fontSize * 2);
        paragraphText.setLeading(25);
        document.add(paragraphText);

        Paragraph end = new Paragraph("十分感谢！",font12);
        end.setLeading(25);//设置段落内行间距，也可使用构造器设置
        end.setFirstLineIndent(25);//首行缩进
        document.add(end);

        // 落款
        Paragraph signer = new Paragraph("小明",font12);
        signer.setLeading(30);//设置段落内行间距，也可使用构造器设置
        signer.setAlignment(Element.ALIGN_RIGHT);
        signer.setIndentationRight(35F);
        document.add(signer);

        Paragraph department = new Paragraph("三年二班",font12);
        department.setAlignment(Element.ALIGN_RIGHT);
        department.setLeading(30);
        department.setIndentationRight(25F);
        document.add(department);

        Paragraph date = new Paragraph("2023年9月8日",font12);
        date.setAlignment(Element.ALIGN_RIGHT);
        date.setLeading(30);
        date.setIndentationRight(20F);
        document.add(date);

        //空行
        Paragraph endLine = new Paragraph("\n", font12);
        endLine.setSpacingAfter(10f);
        document.add(endLine);

        //表格
        //创建表格
        PdfPTable table = new PdfPTable(9);

        table.setWidthPercentage(100);
        table.setTotalWidth(500);
        float[] widths = {15,10,10,10,10,15,10,5,10};//百分比
        table.setWidths(widths);
        table.setLockedWidth(true);
        table.setHorizontalAlignment(PdfPCell.ALIGN_LEFT);//表格整体 水平居左
        // 第一列
        table.addCell(createHeaderCell("城市"));
        //第二列
        table.addCell(createHeaderCell("邮编"));

        //第三列
        table.addCell(createHeaderCell("数量"));

        // 第四列
        table.addCell(createHeaderCell("单价"));
        // 第五列
        table.addCell(createHeaderCell("交通"));
        // 第六列
        table.addCell(createHeaderCell("住宿"));
        // 第七列
        table.addCell(createHeaderCell("星级"));
        // 第八列
        table.addCell(createHeaderCell("景点"));
        // 第九列
        table.addCell(createHeaderCell("美食"));


        java.util.List<Order> orderList = mockDataList();
        orderList.forEach(x->{
            //加数据
            addCellData(table, x.getCity(), 30);
            addCellData(table, x.getMailNo(), 30);
            addCellData(table, x.getNum(), 30);
            addCellData(table, x.getAccount(), 30);
            addCellData(table, x.getTraffic(), 30);
            addCellData(table, x.getHotel(), 30);
            addCellData(table, x.getStart(), 30);
            addCellData(table, x.getSpot(), 30);
            addCellData(table, x.getFood(), 30);

        });
        //table.setSplitLate(true);
        table.setSpacingBefore(1.0f);
        table.setSpacingAfter(1.0f);
        document.add(table);
    }

    private static java.util.List<Order> mockDataList() {
        List<Order> orderList = new ArrayList<>();
        int size = 10;
        for (int i = 0; i < size; i++) {
            Order order = new Order();
            order.setCity("广州");
            order.setMailNo("12344");
            order.setNum("1");
            order.setAccount("1");
            order.setTraffic("高铁");
            order.setHotel("七天");
            order.setStart("5星级");
            order.setSpot("七星岩");
            order.setFood("暂定");
            orderList.add(order);
        }
        return orderList;
    }

    private static PdfPCell createHeaderCell(String text) {
        PdfPCell cell = new PdfPCell();
        cell.setColspan(1);//必须设置跨列
        cell.setMinimumHeight(25);
        cell.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);//水平居中
        cell.setUseAscender(true);//垂直居中
        cell.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE);//垂直居中
        Paragraph paragraph = new Paragraph(text, font8);
        cell.setPhrase(paragraph);
        cell.setBackgroundColor(Color.gray);
        return cell;
    }


    /**
     * 添加表格数据
     * @param table
     * @param cont
     * @param i
     */
    private static void addCellData(PdfPTable table, String cont, int i) {
        PdfPCell cell1 = new PdfPCell();
        cell1.setColspan(1);
        cell1.setMinimumHeight(i);
        cell1.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);//水平居中
        cell1.setUseAscender(true);//垂直居中
        cell1.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE);//垂直居中
        Paragraph paragraph1 = new Paragraph(cont, font8);
        cell1.setPhrase(paragraph1);
        table.addCell(cell1);
    }

    /**
     * 添加表格数据
     * @param table
     * @param cont
     * @param i
     */
    private static void addCellData(Table table, String cont, int i) {
        Cell cell1 = new Cell(new Paragraph(cont, font8));
        cell1.setColspan(1);
        // cell1.setMinimumHeight(i);
        cell1.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);//水平居中
        cell1.setUseAscender(true);//垂直居中
        cell1.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE);//垂直居中
        table.addCell(cell1);
    }


    /**
     * 资源关闭
     *
     * @throws DocumentException
     * @throws IOException       IO操作异常
     */
    public void close() throws IOException {
        document.close();
        byteArrayOutputStream.close();
    }
    public ByteArrayOutputStream creator(Map<String, Object> map) throws DocumentException, IOException {
        execute(map);
        close();
        return byteArrayOutputStream;
    }
}
